#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <pthread.h>
#include <string.h>
#define DCM_IOCTRL_SETPWM 			(0x10)
#define DCM_TCNTB0				(16384)
#define SLEEPTIME 1000000
#define TUBE_IOCTROL  0x11
#define DOT_IOCTROL   0x12
int led_fd;
unsigned int LEDWORD;
unsigned char LEDCODE[10]= {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
static int dcm_fd = -1;
char *DCM_DEV="/dev/dcm/0raw";
int ei;
int setpwm;
int factor;
void *re;
char *input;
char *req_method;
char num[5];
char speed[5];
char photo[5];
int i = 0,t;
int j = 0;


void delay(int t) {
    int i;
    for(; t>0; t--)
        for(i=0; i<400; i++);
}
//led部分
int initled() {
    led_fd=open("/dev/led/0raw",O_RDWR);
    if (led_fd < 0) {
        printf("####Led device open fail####\n");
        return 0;
    }
    return 1;
}
void* ledshow() {
    LEDWORD=(LEDCODE[num[0]-'0']<<8)|(LEDCODE[num[1]-'0']);
    ioctl(led_fd,0x12,LEDWORD);
    usleep(SLEEPTIME);
    close(led_fd);
}
//备用
void* ledClose() {
    close(led_fd);
}

//电动机部分

int initecm() {
    setpwm=0;
    factor = DCM_TCNTB0/1024;
    if((dcm_fd=open(DCM_DEV, O_WRONLY))<0) {
        printf("Error opening %s device\n", DCM_DEV);
        return 0;
    }
    return 1;
}
void *power() {
    setpwm=(speed[0]-'0')*10+(speed[1]-'0');
    for (j; j<=250; j++) {
        ioctl(dcm_fd, DCM_IOCTRL_SETPWM, (setpwm * factor));
        delay(500);
    }
}
char* getcgidata(FILE* fp, char* requestmethod);
int main() {
    //led和motor的线程
    pthread_t led_thread,motor_thread;
//     printf("Content-type: text/plain; charset=iso-8859-1\n\n");
    printf("Content-type: text/html\n\n");
    printf("The following is query reuslt:<br><br>");
    req_method = getenv("REQUEST_METHOD");
    input = getcgidata(stdin, req_method);
    //初始化检测
    if(!(initecm()&&initled())) {
        printf("initialize failed!\n");
        exit(0);
    }


    //num=四个字符
    i=4;
    //led显示的数字两位数
    while(input[i]!='&') {
        num[j++]=input[i++];
    }
    num[j]='\0';
    pthread_create(&led_thread,NULL,ledshow,NULL);
    //speed
    j=0;
    //num=&speed=
    i=13;
    t=2;
    //这里在上一版中有很严重的错误。因为post过来的数据最后是没有&符号的。
    while(t--) {
        speed[j++]=input[i++];
    }
    speed[j]='\0';

    pthread_create(&motor_thread,NULL,power,0);
    pthread_join(led_thread,&re);
    pthread_join(motor_thread,&re);
    return 0;
}




char* getcgidata(FILE* fp, char* requestmethod) {
    char* input;
    int len;
    int size = 1024;
    int i = 0;

    if (!strcmp(requestmethod, "GET")) {
//从这里可以看出来，GET在cgi中传递的Username="admin"&Password="aaaaa"被放置在环境变量QUERY_STRING中了。
        input = getenv("QUERY_STRING");
        return input;
    } else if (!strcmp(requestmethod, "POST")) {
        len = atoi(getenv("CONTENT_LENGTH"));
        input = (char*)malloc(sizeof(char)*(size + 1));
        if (len == 0) {
            input[0] = '\0';
            return input;
        }
        while(1) {            //从这里可以看出来，POST在cgi中传递的Username="admin"&Password="aaaaa"被写入stdin标准输入流中了。
            input[i] = (char)fgetc(fp);
            if (i == size) {
                input[i+1] = '\0';
                return input;
            }
            --len;
            if (feof(fp) || (!(len))) {
                i++;
                input[i] = '\0';
                return input;
            }
            i++;
        }
    }
    return NULL;
}
